package com.bsoft.gol.hcs.clinical.dao;


import com.bsoft.gol.hcs.clinical.bean.req.QueryDrugInformationRequest;
import com.bsoft.gol.hcs.clinical.bean.vo.BaseDrugVo;
import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.spring.boot.annotation.SsdevDao;
import ctd.util.annotation.RpcService;
import ctd.util.converter.ConversionUtils;
import hcn.base.drug.BaseDrug;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import com.bsoft.gol.hcs.utils.CommonUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@SsdevDao( serviceId = "baseDrugDAOService")
public abstract class BaseDrugDAO extends HibernateSupportDelegateDAO<BaseDrug> {
    public BaseDrugDAO() {
        this.setKeyField("drugId");
    }



    /**
     * @Description: 获取本地药品信息
     * @Author: zhaorb
     * @Date: 2020/5/22 15:20
     **/
    public List<BaseDrugVo> queryLocalDrugInformation(final QueryDrugInformationRequest request) {
        HibernateStatelessResultAction<List<BaseDrugVo>> action = new AbstractHibernateStatelessResultAction<List<BaseDrugVo>>() {
            @Override
            public void execute(StatelessSession ss) {
                StringBuffer stringBuffer = getDrugInformationStringBuffer(request);
                Query sqlQuery = ss.createSQLQuery(stringBuffer.toString());
                if (StringUtils.isNotEmpty(request.getHospitalCode())) {
                    sqlQuery.setParameter("hospitalCode",request.getHospitalCode());
                }
                if (StringUtils.isNotEmpty(request.getKeyWord())) {
                    sqlQuery.setParameter("keyWord",request.getKeyWord()+"%");
                }
                int first = request.getPageNo() > 0 ? (request.getPageNo() - 1) * request.getPageSize() : 0;
                sqlQuery.setFirstResult(first);
                sqlQuery.setMaxResults(request.getPageSize());
                sqlQuery.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> dbList = sqlQuery.list();
                setResult(mapToList(dbList));
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    private StringBuffer getDrugInformationStringBuffer(QueryDrugInformationRequest request){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("SELECT c.drug_id drugId,a.org_drug_id orgDrugId,d.drug_name drugName,a.org_factory_id orgFactoryId,a.org_factory_name orgFactoryName," +
                "d.drug_grade drugGrade,c.specification,c.min_pack_unit minPackUnit,c.price,c.pack_unit packUnit,d.dose,d.dose_unit doseUnit,d.usage_name usageName," +
                "d.usage_code usageCode,d.frequency_code frequencyCode,d.frequency_name frequencyName,c.take_way takeWay,d.drug_type as drugType FROM base_org_drug a ");
        stringBuffer.append(" INNER JOIN base_drug_contrast b ON a.object_drug_id = b.object_drug_id ");
        stringBuffer.append(" INNER JOIN base_drug c ON b.drug_id = c.drug_id ");
        stringBuffer.append(" INNER JOIN base_currency_drug d ON c.drug_info_id = d.drug_info_id WHERE 1 = 1 and a.status='1' and c.status='1' and d.status='1' ");
        if (StringUtils.isNotEmpty(request.getHospitalCode())) {
            stringBuffer.append(" and a.object_id =:hospitalCode");
        }
        if (StringUtils.isNotEmpty(request.getKeyWord())) {
            stringBuffer.append(" and (d.pinyin_code like :keyWord or d.drug_name like :keyWord)");
        }
        if (CommonUtils.isNotEmpty(request.getDrugType())) {
            if (request.getDrugType().length()==1) {
                stringBuffer.append(" and d.drug_type = "+request.getDrugType());
            }else {
                String[] split = request.getDrugType().split(",");
                if (split.length==2) {
                    stringBuffer.append(" and (d.drug_type = "+split[0]+ " or d.drug_type = "+split[1]+" )");
                }
            }
        }
        return stringBuffer;
    }

    public  BigInteger queryLocalDrugInformationTotal(final QueryDrugInformationRequest request){
        HibernateStatelessResultAction<BigInteger> action = new AbstractHibernateStatelessResultAction<BigInteger>() {
            @Override
            public void execute(StatelessSession ss) {
                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append("select COUNT(0) from ( "+getDrugInformationStringBuffer(request)+" ) t");
                Query sqlQuery = ss.createSQLQuery(stringBuffer.toString());
                if (StringUtils.isNotEmpty(request.getHospitalCode())) {
                    sqlQuery.setParameter("hospitalCode",request.getHospitalCode());
                }
                if (StringUtils.isNotEmpty(request.getKeyWord())) {
                    sqlQuery.setParameter("keyWord",request.getKeyWord()+"%");
                }
                List list = sqlQuery.list();
                if (list.size() == 1) {
                    Object o = list.get(0);
                    BigInteger count = (BigInteger) o;
                    setResult(count);
                }
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public List<BaseDrugVo> querySingleDrugInformation(final String orgDrugId){
        HibernateStatelessResultAction<List<BaseDrugVo>> action = new AbstractHibernateStatelessResultAction<List<BaseDrugVo>>() {
            @Override
            public void execute(StatelessSession ss) {
                QueryDrugInformationRequest request = new QueryDrugInformationRequest();
                StringBuffer stringBuffer = getDrugInformationStringBuffer(request);
                stringBuffer.append(" and a.org_drug_id =:orgDrugId");
                Query sqlQuery = ss.createSQLQuery(stringBuffer.toString());
                if (StringUtils.isNotEmpty(request.getHospitalCode())) {
                    sqlQuery.setParameter("hospitalCode",request.getHospitalCode());
                }
                if (StringUtils.isNotEmpty(request.getKeyWord())) {
                    sqlQuery.setParameter("keyWord",request.getKeyWord()+"%" );
                }
                if (CommonUtils.isNotEmpty(request.getDrugType())) {
                    sqlQuery.setParameter("drugType",request.getDrugType());
                }
                if (CommonUtils.isNotEmpty(orgDrugId)) {
                    sqlQuery.setParameter("orgDrugId",orgDrugId);
                }
                sqlQuery.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> dbList = sqlQuery.list();
                setResult(mapToList(dbList));
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    private List<BaseDrugVo> mapToList(List<Map> maps){
        List<BaseDrugVo> baseDrugVos = new ArrayList<>();
        for (Map map : maps) {
            baseDrugVos.add(ConversionUtils.convert(map, BaseDrugVo.class));
        }
        return baseDrugVos;
    }

    @RpcService
    public List<String> queryOrgDrugIdList(final String pastOrgId,final String orgId, final List<String> orgDrugIdList) {
        HibernateStatelessResultAction<List<String>> action = new AbstractHibernateStatelessResultAction<List<String>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuffer sql = new StringBuffer();
                sql.append("SELECT\n" +
                        "\td.drug_id drugId,d.object_drug_id orgDrugId\n" +
                        " FROM\n" +
                        " \tbase_org_drug a,\n" +
                        " \tbase_drug_contrast b,\n" +
                        " \tbase_drug c,\n" +
                        " (SELECT\n" +
                        " \th.drug_id,f.object_drug_id\n" +
                        " FROM\n" +
                        " \tbase_org_drug f,\n" +
                        " \tbase_drug_contrast g,\n" +
                        " \tbase_drug h\n" +
                        " WHERE\n" +
                        " \tf.object_drug_id = g.object_drug_id\n" +
                        " AND g.drug_id = h.drug_id\n" +
                        " AND f.delete_status = '0'\n" +
                        " AND h.delete_status = '0'\n" +
                        " AND g.check_status = '1'\n" +
                        " AND f.status = '1'\n" +
                        " AND h.status = '1'\n" +
                        " AND f.object_id =:pastOrgId\n" +
                        " AND f.org_drug_id IN (:orgDrugIdList)\n" +
                        " ) d\n" +
                        " WHERE\n" +
                        " \ta.object_drug_id = b.object_drug_id\n" +
                        " and c.drug_id = d.drug_id \n" +
                        " AND b.drug_id = c.drug_id\n" +
                        " AND a.delete_status = '0'\n" +
                        " AND c.delete_status = '0'\n" +
                        " AND b.check_status = '1'\n" +
                        " AND a.status = '1'\n" +
                        " AND c.status = '1'\n" +
                        " AND a.object_id =:orgId\n" +
                        "\n");
                Query query = ss.createSQLQuery(sql.toString());
                query.setParameter("pastOrgId", pastOrgId);
                query.setParameter("orgId", orgId);
                query.setParameterList("orgDrugIdList",orgDrugIdList);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<String> drugList = new ArrayList<String>();
                List<Map> list = query.list();
                if (list.size() > 0) {
                    for (Map map : list) {
                        drugList.add(String.valueOf(map.get("orgDrugId")));
                    }
                }
                setResult(drugList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    @RpcService
    public List<Map<String,Object>> queryOrgDrugIds(final String orgId, final String specification, final  String dosageFormCode ,final String orgDrugName) {
        HibernateStatelessResultAction<List<Map<String,Object>>> action = new AbstractHibernateStatelessResultAction<List<Map<String,Object>>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuffer sql = new StringBuffer();
                sql.append("SELECT " +
                        " a.object_drug_id orgDrugId " +
                        " FROM " +
                        " base_org_drug a, " +
                        " base_drug_contrast b," +
                        " base_drug c," +
                        "  base_currency_drug d" +
                        " WHERE" +
                        " a.object_drug_id = b.object_drug_id" +
                        " and c.drug_info_id = c.drug_info_id " +
                        " AND b.drug_id = c.drug_id" +
                        " AND a.delete_status = '0'" +
                        " AND c.delete_status = '0'" +
                        " AND b.check_status = '1'" +
                        " AND a.status = '1'" +
                        " AND c.status = '1'" +
                        " AND (a.org_drug_name =:orgDrugName or d.drug_name =:orgDrugName )" +
                        " AND a.dosage_form_code =:dosageFormCode " +
                        " AND a.specification =:specification " +
                        " AND a.object_id =:orgId");
                Query query = ss.createSQLQuery(sql.toString());
                query.setParameter("specification", specification);
                query.setParameter("orgId", orgId);
                query.setParameter("orgDrugName", orgDrugName);
                query.setParameter("dosageFormCode", dosageFormCode);
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map<String,Object>> list = query.list();
                setResult(list);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }


    @DAOMethod(sql = " from BaseDrug where drugInfoId=:drugInfoId and  factoryId=:factoryId and specification=:specification")
    public abstract  BaseDrug getBaseDrug(@DAOParam("drugInfoId")Integer drugInfoId, @DAOParam("factoryId")Integer factoryId, @DAOParam("specification")String specification);
    /**
     * 查询标准药品
     * @param drugInfoId
     * @return
     */
    public List<hcn.base.drug.vo.BaseDrugVo> findDrugList(final Integer drugInfoId){
        HibernateStatelessResultAction<List<hcn.base.drug.vo.BaseDrugVo>> action = new AbstractHibernateStatelessResultAction<List<hcn.base.drug.vo.BaseDrugVo>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuffer stringBuffer =new StringBuffer();
                stringBuffer.append(" select b.drug_id as drugId,b.drug_info_id as drugInfoId,b.factory_id as factoryId,b.trade_name as tradeName,b.specification,b.min_pack_unit as minPackUnit,");
                stringBuffer.append(" b.pack_unit as packUnit,b.price,b.approval_no as approvalNo,b.status,b.enable_dt as enableDt,b.enable_user as enableUser,b.create_dt as createDt,b.modify_dt as modifyDt,b.modify_user as modifyUser,b.delete_status as deleteStatus,f.short_name as shortName,f.factory_code as factoryCode from base_drug b,base_factory f where b.factory_id=f.factory_id");
                stringBuffer.append(" and b.drug_info_id= '"+drugInfoId+"'");
                stringBuffer.append(" order by b.modify_dt desc");
                Query sqlQuery = ss.createSQLQuery(stringBuffer.toString());
                sqlQuery.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> dbList = sqlQuery.list();
                List<hcn.base.drug.vo.BaseDrugVo> baseDrugVos = new ArrayList<>();
                for (Map map : dbList) {
                    baseDrugVos.add(ConversionUtils.convert(map, hcn.base.drug.vo.BaseDrugVo.class));
                }
                setResult(baseDrugVos);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
}
